﻿using LumiSoft.Net.Mail;
using LumiSoft.Net.MIME;
using LumiSoft.Net.POP3.Client;
using SUNRPA.CONTROLS.IMPL.domain;
using System.Runtime.InteropServices;
using System.Text;
using System.Text.RegularExpressions;

namespace SUNRPA.CONTROLS.IMPL.util {
    public class POP3EmailUtil{
        private static string regex = @"=\?(?<encode>.*?)\?(?<type>[B|Q])\?(?<body>.*?)\?=";
        private Regex encodeRe = new Regex(regex, RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace | RegexOptions.Multiline);
        
        public POP3_Client client = new POP3_Client();
        
        ~POP3EmailUtil() { 
            client.Dispose();
        }

        /// <summary>
        /// 乱码解析
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        private string GetMailText(string input){
            try{
                MatchCollection mcs = encodeRe.Matches(input);
                foreach (Match mc in mcs){
                    string encode = mc.Groups["encode"].Value;
                    string type = mc.Groups["type"].Value;
                    Encoding encoding = null;
                    if (!string.IsNullOrEmpty(encode)){
                        if ((encode.ToLower().Contains("gbk") || encode.ToLower().Contains("utf8") || encode.ToLower().Contains("utf-8")) && type == "Q"){
                            if (encode.ToLower().Contains("utf-8")){
                                encoding = Encoding.UTF8;
                            }else if (encode.ToLower().Contains("gbk")){
                                encoding = Encoding.GetEncoding("gb2312");
                            }
                            input = input.Replace(mc.Value, QuotedPrintable.Decode(mc.Groups["body"].Value, encoding));
                        }else{
                            if (encode.ToLower().Contains("euccn") || encode.ToLower().Contains("euc-cn")){
                                encode = "gb2312";
                            }
                            else if (encode.ToLower().Contains("utf8")){
                                encode = "utf-8";
                            }
                            string body = mc.Groups["body"].Value;
                            byte[] bytes = Convert.FromBase64String(body);
                            string result = Encoding.GetEncoding(encode).GetString(bytes);
                            input = input.Replace(mc.Value, result);
                        }
                    }
                }
                return input;
            } catch (Exception){
                return input;
            }
        }

        public POP3EmailUtil(string popServer, int port, bool ssl) {
            client.Connect(popServer, port, ssl);
        }

        public void Login(string user, string password) { 
            client.Login(user, password);
        }
        public void SendEmail(){ 
            
        }

        public EmailModel GetEmail([Optional]string titleFilter,[Optional]string contentFilter){
            EmailModel model = null;
            POP3_ClientMessageCollection messages = client.Messages;
            int endcount = messages.Count - 1;
            if(messages.Count > 50) { 
                endcount = 50;
            }
            for(int i = 0; i <= endcount; i++) {
                POP3_ClientMessage message = messages[i];
                Mail_Message mimeMessage = Mail_Message.ParseFromByte(message.MessageToByte());
                Mail_Message messageHeader = Mail_Message.ParseFromByte(message.HeaderToByte());
                if(mimeMessage == null){
                    continue;
                }
                Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
                string body = GetMailText(mimeMessage.BodyText);
                if(!string.IsNullOrEmpty(mimeMessage.BodyHtmlText)) {
                    body = GetMailText(mimeMessage.BodyHtmlText);
                }
                string title = GetMailText(messageHeader.Subject);
                if(!string.IsNullOrEmpty(contentFilter)){ 
                    if(!body.Contains(contentFilter)){ 
                        continue;
                    }
                }
                if(!string.IsNullOrEmpty(titleFilter)) {
                    if(!title.Contains(titleFilter)) {
                        continue;
                    }
                }
                List<String> to = new List<string>();
                List<String> copyTo = new List<string>();
                foreach(Mail_t_Mailbox recipient in messageHeader.To.Mailboxes) {
                    string displayname = recipient.DisplayName;
                    string address = recipient.Address;
                    to.Add(displayname + "&" + address);
                }
                if(messageHeader.Cc != null) { 
                    foreach(Mail_t_Mailbox recipient in messageHeader.Cc.Mailboxes) {
                        string displayname = recipient.DisplayName;
                        string address = recipient.Address;
                        copyTo.Add(displayname + "&" + address);
                    }
                }
                model = new EmailModel(){ 
                    Body = body,
                    Title = title,
                    SendDate = messageHeader.Date,
                    From = messageHeader.From[0].DisplayName + "&" + messageHeader.From[0].Address,
                    To = to,
                    CopyTo = copyTo,
                    Uid = message.UID,
                    OriginalObj = message
                };
                break;
            }
            return model;
        }

        public string SaveAttach(POP3_ClientMessage message, string savePath) { 
            Mail_Message mimeMessage = Mail_Message.ParseFromByte(message.MessageToByte());
            MIME_Entity[] attaches = mimeMessage.GetAttachments(true, true);
            //暂时只要第一个附件
            foreach(MIME_Entity attach in attaches) {
                //只要附件，不要内嵌图片
                if(attach.ContentDisposition.DispositionType == MIME_DispositionTypes.Attachment) { 
                    string fileName = attach.ContentType.Param_Name;
                    string filePath = savePath + Path.DirectorySeparatorChar + fileName;
                    MIME_b_SinglepartBase body = (MIME_b_SinglepartBase)attach.Body;
                    FileUtil.CreateFile (filePath, body.Data);
                    return filePath;
                }
            }
            return null;
        }
    }
}
